import psutil
import tkinter as tk
from scapy.all import *
from tkinter import filedialog, messagebox
from tkinterdnd2 import DND_FILES, TkinterDnD


def replay_pcap(filename, iface):
    """
    读取指定数据包并将内容重放到指定网卡中

    :param filename: 数据包文件路径
    :param iface: 网卡名称
    :return: None
    """
    try:
        packets = rdpcap(filename)  # 读取pcap文件中的数据包
        for packet in packets:
            sendp(packet, iface=iface, verbose=0)  # 发送数据包到指定网卡
            print(f"Replaying packet: {packet.summary()}")  # 打印重放的数据包摘要
    except Exception as e:
        messagebox.showerror("Error", f"Error: {e}")


def on_file_drop(event):
    filename = event.data
    if filename.endswith(".pcapng") or filename.endswith(".pcap"):
        replay_pcap(filename, iface_name)
        messagebox.showinfo("Success", "数据包重放完成！")
    else:
        messagebox.showerror("Error", "请选择一个pcap文件！")


def browse_file():
    filename = filedialog.askopenfilename(filetypes=[("PCAP files", "*.pcap")])
    if filename:
        replay_pcap(filename, iface_name)
        messagebox.showinfo("Success", "数据包重放完成！")


def get_network_interfaces():
    interfaces = psutil.net_if_addrs()
    interface_names = list(interfaces.keys())
    return interface_names


def show_selection():
    global iface_name
    iface_name = interfaces[var.get()]


if __name__ == '__main__':
    iface_name = ''

    # 创建主窗口
    root = TkinterDnD.Tk()

    root.title("数据包重放工具")

    # 标签和输入框
    tk.Label(root, text="请选择网卡接口名称：").pack(pady=5, anchor='w')
    # interface_entry = tk.Entry(root, width=30)
    # interface_entry.pack()

    # 创建 IntVar 变量用于存储选择的值
    var = tk.IntVar()
    interfaces = get_network_interfaces()
    radios = list()
    for i, interface in enumerate(interfaces):
        radios.append(tk.Radiobutton(root, text=interface, variable=var, value=i, command=show_selection))

    for radio in radios:
        radio.pack(pady=10, anchor='w')



    # 文件上传框
    drop_label = tk.Label(root, text="将pcap文件拖放到此处进行重放", bg="lightgray", width=50, height=5)
    drop_label.pack(pady=20)

    # 绑定拖放事件
    drop_label.drop_target_register(DND_FILES)
    drop_label.dnd_bind('<<Drop>>', on_file_drop)

    # 浏览文件按钮
    browse_button = tk.Button(root, text="浏览文件", command=browse_file)
    browse_button.pack(pady=10)

    # 运行主循环
    root.mainloop()
